/* revised based on the source file from libMaskv6 for pylibMask using SWIG.
 * done by Yongbo Tang, 20121108 
 *
 * Mask header file.
 * 
 * Copyright (c) 1993-2010 Leo Spiekman, Xaveer Leijtens
 *
 * This file is part of libMask.
 *
 * libMask is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * libMask is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with libMask.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _MASK_INCLUDED
#define _MASK_INCLUDED

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include "msk_technology.h"


#define TRUE    1
#define FALSE   0

#ifndef M_PI
#define M_PI          3.14159265358979323846
#endif

/* Mask layer color definition */
#define WHITE       1
#define RED         2
#define YELLOW      3
#define GREEN       4
#define CYAN        5
#define BLUE        6
#define MAGENTA     7
#define BLACK       8
#define DK_GREEN    9
#define AQUA        10
#define DK_BLUE     11
#define PURPLE      12
#define MAUVE       13
#define ORANGE      14
#define BROWN       15
#define TAN         16
/* Additional colors (break compatibility with EGS) */
#define PINK        17

/* state of pen_up() or pen_down(). */
#define PENDOWN   1
#define PENUP     0

#define VISIBLE     TRUE
#define INVISIBLE   FALSE

//output format
#define FORMAT_GDS 1
#define FORMAT_CIF 2
#define FORMAT_EGS 3

#ifndef SWIG
#define END_LAYERS    {-1,NULL,0,INVISIBLE,0}
#define END_LAYOUTMAP {NULL,NULL}
#define END_LAYNUMMAP {0,0}
#endif

struct Layer{
  int number;
  const char *name;
  int color;
  int visible;
  double eps;
};

#ifndef SWIG
struct layoutmap {
  const char *fr;
  const char *to;
};

struct laynummap {
  const int fr;
  const int to;
};
#endif

struct geom_lal {
  double line1;
  double ang;
  double line2;
};

struct geom_al {
  double ang;
  double line;
};

struct geom_ala {
  double ang1;
  double line;
  double ang2;
};

#ifndef SWIG
/* Global variables */
extern double sw_overlap;
extern double cw_overlap;

extern struct Layer layers[];
extern struct Layer *players;  ///TYB

extern int clayer;
extern int num_layout;
extern int this_layout;

/* Sublayout definition */
#define TMP_NAME_TMPL ("/tmp/msk_tmp_")
extern void sublayout_file(int n);
#define MAIN_LAYOUT 0
#define MSK_MAX_LAYOUTS 512

struct layout {
  const char *name;
  void (*func)(int);
};

extern struct layout layouts[];

#endif

/* Pointer stack definition */

struct pointer {
  double x,y;                       /* Generating coordinates */
  double a;                         /* Angle (radians) */
  int flip;                         /* Flip about x-axis */
};

#define STACK_DEPTH 100

#ifndef SWIG
extern struct pointer pstack[STACK_DEPTH];  /* Pointer stack */
extern struct pointer *pstackp;             /* Pointer stack pointer */
#endif


extern struct pointer cp;                   /* Current generating position */
#define FLIP        TRUE
#define NOFLIP      FALSE

double RAD(double);//for SWIG
double DEG(double);//for SWIG implemented in util.cc
//#define RAD(deg)    ((deg)/180.0*M_PI)
//#define DEG(rad)    ((rad)*180.0/M_PI)

/* Generating mode flags */
extern unsigned int mode;
#define FLATTENED   0x01        /* Include sublayouts in main layout */
#define PATGEN      0x02	/* For pattern generator instead of EBPG */
#define CANON       0x04	/* Projection masks with CANON */
#define FILLED	    0x08        /* Generate filled or outline EGS patterns */
#define CWARC       0x10	/* Use EGS arc (3 points) */
#define CWANGLE     0x20	/* Use EGS radius and angle arcs */
#define POLYGON     0x40	/* Use polygons in stead of polylines */
#define GRIDDED     0x80	/* Output EGS on a 1 nm grid */

#ifndef SWIG
/* Low-level subroutines and EGS/CIF primitives */
extern int output_format;
extern FILE *MASK;

void mask_output(const int);
void mask_init(void);
void main_layout(void);
#endif

/* utilities */
double map_0_2pi(double);
double radius_3pts(double,double,double,double,double,double,double*,double*);

/* The EGS/CIF low-level functions. */
int msk_header(const char *, const char *);
void msk_trailer();

void msk_sublayout_header(const char *);
/* void msklayout_trailer(); */

void msk_sublayout_trailer();
void msk_sublayout(int);

#ifndef SWIG
int msk_add_sublayout(const char *, void (*)(int));
void msk_main_header(const char *);
void mskpolygonN(int,double *,double *, int);
void mskline(int,double,double,double,double,double);
void mskpolygon3(int,double,double,double,double,double,double);
void mskpolygon4(int,double,double,double,double,double,double,double,double);
void mskarc(int,double,double,double,double,double,double,double);
void mskarc2(int,double,double,double,double,double,double);
void mskcircle(int,double,double,double,double,double);
void mskpolystart(int,double);
void mskpolygonstart(int);
void mskpolypoint(int,double,double);
void mskpolyend(int);
void mskpolygonend(int);
void sublayout_input(const char *, const struct laynummap *, const struct layoutmap *);
void msklayout(const int, const char *,double,double,double,int);
void msktext(int,double,double,double,double,char *);
#endif



/* Pointer handling */
#ifndef SWIG
void makeabs(struct pointer *,struct pointer);
void makerel(struct pointer *,struct pointer);
void init_cp(void);
void init_pstack(void);
void print_pstack(void);
#endif

void push_cp(void);
void pop_cp(void);
void drop(void);
void org(double,double,double,int);
void move(double,double,double,int);
void movept(double,double,int,int);
void skip(double);
void offset(double);
void rotate(double);
void print_abscp(void);
void print_relcp(void);
void show_cp(double);

/* Environment handling */
#ifndef SWIG
void setlayers(struct Layer *);///TYB
void insertlayer(struct Layer &);//TYB
struct Layer *getlayers(void);///TYB
#endif

void layer(int);
double getlayer_accuracy(int);
void setlayer_accuracy(int, double);
int currentlayer(void);
int drawlayer(int);
int pen_up();
int pen_down();
int getlayer_visibility(int);
void setlayer_visibility(int, int);

#ifndef SWIG
struct Layer *layernr(int);
struct layout *layoutnr(int);
void output_layout(int);
#endif
/* Text handling */

void setfont(char *);
void textout(const char *,double);
void textout_stretch(const char *,double,double);

/* Components */
void sw(double,double);
void set_sw_overlap(double);
double get_sw_overlap(void);
void cw(double r,double a,double w);
void set_cw_overlap(double);
double get_cw_overlap(void);

void sw2(double,double,double);
void cw2(double,double,double,double);
void cwg_curve_rect(double,double,double,double,int,int);
void curve_rect(double,double,double,int);

void triangle(double,double,double,double);
void isosceles_triangle(double,double);
void rect(double l,double w,int p1,int p2);
void box(double, double, double);

void taper(double l,double w1,double w2);
void taper_parabolic(double,double,double);
void taper_angle(double,double,double,double);
void taper2(double,double,double,double,double);

void corner90(double,double);
void circle(double,double);
void disc(double);

void sw3(double,double,double,double);
void cw3(double,double,double,double,double);
void taper3(double,double,double,double,double,double,double);
double sbend(double,double,double,double);
double adiabend(double, double, double, int);

struct geom_al arc_line(double,double,double,double,double);
struct geom_ala arc_line_arc(double,double,double,double,double,double,double,double);
struct geom_lal line_arc_line(double,double,double,double,double,double);

void mmi_1x1(double,double,double,double,double,double);
void mmi_2x2(double,double,double,double,double,double,double,double);
void mmi_1x2(double,double,double,double,double,double,double);
void mmi_1x1taper(double,double,double,double,double,double,double,double);
void mmi_1x2taper(double,double,double,double,double,double,double,double,double);
void mmi_2x2taper(double,double,double,double,double,double,double,double,double,double);
void reflector_1x0(double, double, double, double, double, double);
void reflector_2x0(double, double, double, double, double, double, double);
void butterfly_reflector_2x0_s(double, double,	 double, double, double, double, double o2, double, double, double);
void butterfly_reflector_2x0(double, double,	 double, double, double, double, double, double, double);

#ifndef SWIG
void block(double l,double w,int p1,int p2);
void polyline(double,double,int,int);
void npolyline(double[],double[],int,double);
void polylingo(double[],double[],int,double);
int  arc_arc(double,double,double,double,double,double*,double*);
#endif

/* Standard layout components */

void window(const char *);
void varwindow(const char *,double,double,double,double,double,double,double,double);
void var2window(const char *,double,double,double,double,double,double,double,double,double);
void marker1(void);
void marker2(void);
void EBL_global_mark();
void EBL_local_mark(double, double, int);
void nonius(void);

#ifndef SWIG
//it seems they are not included in libMaskV6
void vernier1(const char);
void vernier2(const char);
#endif

extern char *libMaskVersion();

#ifndef SWIG
#define libEgsVersion() libMaskVersion()
#endif

#endif /* _MASK_INCLUDED */
